using System.Reflection;
using Game;
using GameEntitySystem;
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型。

namespace SCIENEW {
    /// <summary>
    /// 控制具有合成类型的方块
    /// </summary>
    public static class IECrafterManager {
        public static List<(Type Component, Type[] Devices)> componentToCrafterDevice = new();
        public static Dictionary<int, int[]> heatLevelToDeviceID = new();

        public static void Init() {
            //获取所有接了ICrafterComponent接口的component
            var types = Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(Component).IsAssignableFrom(t) && typeof(ICrafterComponent).IsAssignableFrom(t) && t.IsClass);
            Assembly currentAssembly = Assembly.GetExecutingAssembly();
            Assembly gameManagerAssembly = typeof(GameManager).Assembly;

            // 只遍历这两个程序集
            var assemblies = new[] { currentAssembly, gameManagerAssembly };

            foreach (Type targetType in types) {
                Type targetInterface = typeof(ICrafterDevice<>).MakeGenericType(targetType);
                List<Type> deviceTypes = new();
                foreach (var assembly in assemblies)
                {
                    deviceTypes.AddRange(assembly.GetTypes().Where(t => targetInterface.IsAssignableFrom(t) && t.IsClass));
                }
                if(deviceTypes.Count > 0) componentToCrafterDevice.Add((targetType, deviceTypes.ToArray()));

            }
        }

        /// <summary>
        /// 寻找符合热值的目标ICrafterComponent，再寻找接了ICrafterDevice《目标ICrafterComponent》的所有设备类型
        /// </summary>
        /// <param name="heat"></param>
        /// <returns></returns>
        static Type[]? GetCrafterDeviceByHeatLevel(int heat)
        {
            foreach (var pair in componentToCrafterDevice)
            {
                var requiredHeatLevelProperty = pair.Component.GetProperty("RequiredHeatLevel", BindingFlags.Static | BindingFlags.Public);
                if (requiredHeatLevelProperty != null)
                {
                    int requiredHeatLevel = (int)requiredHeatLevelProperty.GetValue(null);
                    if (requiredHeatLevel == heat)
                    {
                        return pair.Devices;
                    }
                }
            }
            return null; // 未找到匹配的组件和设备
        }

        /// <summary>
        /// 寻找符合热值的目标ICrafterComponent，
        /// 再寻找接了ICrafterDevice《目标ICrafterComponent》的所有设备类型，
        /// 最后输出这些设备类型对应的设备的方块ID
        /// </summary>
        /// <param name="requiredHeat"></param>
        /// <returns></returns>
        public static int[] GetCrafterDevice(int requiredHeat) {
            if (heatLevelToDeviceID.TryGetValue(requiredHeat, out int[] devices)) return devices;

            Type[]? types = GetCrafterDeviceByHeatLevel(requiredHeat);
            if (types != null && types.Length > 0) {
                List<int> newDevices = new();
                foreach (var deviceType in types) {
                    int deviceID = DevicesBlockManager.GetDeviceValueByType(deviceType);
                    if(deviceID != 0) newDevices.Add(deviceID);
                }
                heatLevelToDeviceID.Add(requiredHeat, newDevices.ToArray());
                return newDevices.ToArray();
            }
            return [0];
        }
    }
}